package org.odst.transformer;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.odst.formula.Formula;
import org.odst.formula.ListRange;
import org.odst.parser.Cell;
import org.odst.processor.CellProcessor;
import org.odst.tag.Block;
import org.odst.util.FormulaUtil;

/**
 * Base class for {@link RowTransformer} impelementations
 * @author Leonid Vysochyn
 * @author Cyril PODER
 */
public abstract class BaseRowTransformer implements RowTransformer{

    protected final Log log = LogFactory.getLog(getClass());

    /**
     * This list is used to store formula cells information while processing template file
     */
    private List<Formula> formulas = new ArrayList<Formula>();
    /**
     * This variable stores all list ranges found while processing template file
     */
    private Map<String, ListRange> listRanges = new HashMap<String, ListRange>();
    /**
     * Stores all named HSSFCell objects
     */
    private Map<String, Cell> namedCells = new HashMap<String, Cell>();

    private List<CellProcessor> cellProcessors = new ArrayList<CellProcessor>();

    Row row;

    public Row getRow() {
        return row;
    }


    /**
     * Adds new {@link org.odst.formula.ListRange} to the map of ranges and updates formulas if there is range with the same name already
     *
     * @param sheet     Sheet to process
     * @param rangeName The name of {@link org.odst.formula.ListRange} to add
     * @param range     actual {@link org.odst.formula.ListRange} to add
     * @return true if a range with such name already exists or false if not
     */
    protected boolean addListRange(Sheet sheet, String rangeName, ListRange range) {
        if (listRanges.containsKey(rangeName)) {
            // update all formulas that can be updated and remove them from formulas list ( ignore all others )
            FormulaUtil.updateFormulas(sheet.getOooSheet(), formulas, listRanges, namedCells, true);
            listRanges.put(rangeName, range);
            return true;
        }
        listRanges.put(rangeName, range);
        return false;
    }


    /**
     * Applies all registered CellProcessors to a cell
     *
     * @param cell - {@link org.odst.parser.Cell} object with cell information
     */
    protected void applyCellProcessors(Cell cell) {
        for (int i = 0; i < cellProcessors.size(); i++) {
            CellProcessor cellProcessor = (CellProcessor) cellProcessors.get(i);
            cellProcessor.processCell(cell, namedCells);
        }
    }

    public Block getTransformationBlock(){
        return null;
    }

    public void setTransformationBlock(Block block) {
    }
}
